﻿using Abp.Application.Services.Dto;
using Abp.AspNetCore.Mvc.Controllers;
using Abp.Domain.Repositories;
using Batman.Cms.Core.Models.Mvc;
using Batman.Jianbei.Forum.Areas.Forum.Converts;
using Batman.Jianbei.Forum.Areas.Forum.Responses;
using Batman.Jianbei.Forum.Controllers.Dicts.Converts;
using Batman.Jianbei.Forum.Core.Domains.Dicts;
using Batman.Jianbei.Forum.Core.Domains.Posts;
using Batman.Jianbei.Forum.Services.Posts;
using Batman.Jianbei.Forum.Services.Posts.Dtos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Abp.Runtime.Caching;
using Batman.Jianbei.Forum.Areas.Forum.Filters;
using Batman.Jianbei.Forum.Services;
using Batman.Core;
using Batman.Jianbei.Forum.Core.Domains.Socials;
using Batman.Jianbei.Forum.Repositories.Mongo;
using MongoDB.Driver;

namespace Batman.Jianbei.Forum.Areas.Forum
{
    [Area("Forum")]
    public class HomeController : AbpController
    {
        public IRepository<Partition, string> PartitionRepo { get; set; }

        public IRepository<Post, string> PostRepo { get; set; }

        public IRepository<PostTint, string> PostLikeRepo { get; set; }

        public PostTintCollection PostLikeCollection { get; set; }

        public IRepository<PostComment, string> CommentRepo { get; set; }

        public PostService PostService { get; set; }

        public AccessRepository AccessRepository { get; set; }


        public ICacheManager CacheManager { get; set; }


        /// <summary>
        /// 首页参数
        /// </summary>
        /// <returns></returns>
        public IActionResult Options()
        {
            var partition_query = PartitionRepo.GetAll().AsNoTracking();

            partition_query = partition_query.Where(t => !t.IsDeleted);

            List<NameValueDto> partions = partition_query.OrderByDescending(t => t.Sort).Select(t => t.ToNameValueDto())
                .ToList();

            return Json(new { partions });
        }

        /// <summary>
        /// 首页获取帖子数据流
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostFlow(PagedResultRequestDto page, PostFilter filter)
        {
            var result = await PostService.GetPostAsync(page, filter, User.GetWxUserId());
            return Json(result);
        }

        /// <summary>
        /// 根据ID获取帖子
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IActionResult Post(string id)
        {
            var post_query = PostRepo.GetAll().AsNoTracking().Where(t => t.Status != Core.Enums.PostStatus.trashed)
                .AsQueryable();

            post_query = post_query.Where(t => t.Id == id);

            post_query = post_query.Include(t => t.WxUser).Include(t => t.Imgs).Include(t => t.Topic)
                .ThenInclude(t => t.Partition).AsQueryable();


            List<PostFlowItem> items = post_query.Select(t => t.ToPostFlowItem()).ToList();

            List<string> postIds = items.Select(t => t.PostId).ToList();
            string wxUId = User.GetWxUserId();
            List<PostTintCount> likeCounts = PostLikeCollection.GetTintCounts(postIds, wxUId);

            var accessCount = AccessRepository.Collection.Find(t => t.PostId == id).CountDocuments();
            //            var accessCount = AccessRepository.Collection.Aggregate()
            //                .Match(Builders<Access>.Filter.Where(t => t.PostId == id))
            //                .
            //                .Count();
            //            
            foreach (PostFlowItem item in items)
            {
                PostTintCount postTintCount = likeCounts.FirstOrDefault(t => t.PostId == item.PostId);
                if (postTintCount == null) continue;

                item.IsLike = postTintCount.IsLike;
                item.LikeCount = postTintCount.LinkCount;
                item.IsFavorite = postTintCount.IsFavorite;
            }

            if (items.Count == 0) return Json(new ResponseBase(false, "帖子不存在，或已删除！"));

            PostFlowItem result = items.FirstOrDefault();
            if (result == null) return Json(new ResponseBase(false, "帖子不存在"));

            result.CommentCount = CommentRepo.GetAll().AsNoTracking().Count(t => !t.IsDeleted && t.PostId == id);
            result.AccessCount = (int)accessCount;

            return Json(result);
        }


        /// <summary>
        /// 点赞或者取消赞
        /// </summary>
        /// <param name="postId"></param>
        /// <returns></returns>
        [Authorize]
        public async Task<IActionResult> Like(string postId)
        {
            var wxUId = User.GetWxUserId();

            Expression<Func<PostTint, bool>> condition = postLike =>
                postLike.PostId == postId && postLike.WxUserId == wxUId;
            bool exists = await PostLikeRepo.GetAll().AsNoTracking().AnyAsync(condition);

            if (exists)
            {
                PostLikeRepo.Delete(condition);
            }
            else
            {
                PostLikeRepo.Insert(PostTint.NewLike(postId, wxUId));
            }

            return Json(new ResponseBase(true));
        }

        /// <summary>
        /// 获取分区
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> Partitions()
        {
            var partitions = await PartitionRepo.GetQuery().Where(t => !t.IsDeleted)
                                                .OrderByDescending(t => t.Sort)
                                                .ThenByDescending(t => t.CreateAt)
                                                .Select(t => new NameValueDto(t.Name, t.Id))
                                                .ToListAsync();

            return Json(partitions);
        }
    }
}